package maze;

/**
 * Directions, in the usual sense - <strong>Mechanisms</strong>, <strong>Controls</strong>.
 * <p>
 * Abstraction of direction, since the 'bot deals with degree values but
 * Controls only cares about the four cardinal directions.</p>
 * 
 * Development stage: should be usable as-is.
 * @author Calvin
 */
public enum Direction {
	/**
	 * Designated null-value
	 */
	NORTH,
	/**
	 * 180 deg from NORTH; i.e., orthogonal to NORTH
	 */
	SOUTH,
	/**
	 * 90 deg from NORTH
	 */
	EAST,
	/**
	 * 270 deg from NORTH
	 */
	WEST;

	/**
	 * @return The reverse of this Direction.
	 */
	public Direction reverse() {
		switch (this) {
		case NORTH:
			return SOUTH;
		case SOUTH:
			return NORTH;
		case EAST:
			return WEST;
		case WEST:
			return EAST;
		default:
			return null;
		}
	}
	
	/**
	 * @return Angle in degrees clockwise from {@value #NORTH}.
	 */
	public Double angle(){
		switch(this) {
		case NORTH:
			return 0.0;
		case EAST:
			return 90.0;
		case SOUTH:
			return 180.0;
		case WEST:
			return 270.0;
		default:
			return null;
		}
	}
	
	/**
	 * Return the cardinal direction corresponding *roughly* to
	 * the specified angle.
	 * @param angle Angle in degrees to estimate.
	 * @return Direction object corresponding to angle.
	 */
	public static Direction estimate(double angle){
		if(angle < -45){
			return estimate(angle+360);
		}else if(angle < 45){
			return NORTH;
		}else if(angle < 135){
			return EAST;
		}else if(angle < 225){
			return SOUTH;
		}else if(angle < 315){
			return WEST;
		}else{
			return estimate(angle-360);
		}
	}
}